import axios from 'axios';
import { N_cPLDetails, T_pldBase, T_task, Tsrv, ifs } from './base';

class T_shceduleHandle extends T_pldBase {
  // 排程任务
  public scheduleTask: T_task = new T_task(10000);

  // 判断排程是否完成
  public schedulingStatus = N_cPLDetails.V_reqStatus.NOTSTART;

  // 排程注册json
  private schedulingJson;

  // 排程任务id
  private taskID: string = '';

  // 正在排程项
  private schedulingItems = [];

  // 每一挂默认加工时间
  private defaulTimes = [];

  private schedulingTime = {
    default: 0, // 默认排程时间：是指按照挂组的默认顺序，进行仿真模拟后计算得到的总时间。
    intelligent: 0 // 智能排产时间：经过启发式智能排查算法后得到的挂组加工顺序，在此顺序下进行加工的总时间。
  };

  // 缓存位信息, key为缓存位名称，hangGroupIdp为挂组id，cacheOrderp为缓存位顺序，hangGroupStatusp为挂组加工状态
  public cacheInfo = new Map([
    [
      '28号缓存位',
      {
        hangGroupIdp: 'my353',
        cacheOrderp: 'my320',
        hangGroupStatusp: 'my3830'
      }
    ],
    [
      '29号缓存位',
      {
        hangGroupIdp: 'my354',
        cacheOrderp: 'my321',
        hangGroupStatusp: 'my3831'
      }
    ],
    [
      '30号缓存位',
      {
        hangGroupIdp: 'my355',
        cacheOrderp: 'my322',
        hangGroupStatusp: 'my3832'
      }
    ],
    [
      '31号缓存位',
      {
        hangGroupIdp: 'my356',
        cacheOrderp: 'my323',
        hangGroupStatusp: 'my3833'
      }
    ]
  ]);

  // 等待加工缓存位的加工状态点位,挂组id,顺序号
  public currentCacheStatus = [
    {
      hangGroupID: undefined, // 0代表复位
      cacheStatusp: '',
      cacheOrderp: '', // 顺序号点位
      order: undefined
    }
  ];

  // 预留挂组信息，只有一挂
  public reserveHangGroupInfo = {
    hangGroupID: undefined,
    order: undefined,
    cacheStatusp: '',
    cacheOrderp: ''
  };

  // 排程前处理
  public beforeSchedule(val: Array<any>) {
    // 先过滤当前产线的挂组信息，再过滤挂组状态f_status大于1小于5的挂组信息
    const filterVal = val.filter(
      el => el.master_bill_id === this.self.formData.id
    );
    // 需排程的挂组数据
    const scheData = [];
    // 判断是否有加工中的挂组信息
    const filterVal1 = filterVal.filter(el1 => el1.f_status === 5);
    // 存在加工中挂组
    if (!Tsrv.noValue(filterVal1)) {
      // 排程补丁逻辑：新增预留位（最小顺序的已排程挂组），不管排程结果是否出来，行车都优先调用预留位
      if (Tsrv.noValue(this.reserveHangGroupInfo.hangGroupID)) {
        // 已排程挂组
        const currentHangGroups = filterVal.filter(el => el.f_status === 4);

        const minOrderItem = this.currentCacheStatus.reduce((min, item) => {
          if (
            currentHangGroups.find(el => el.physical_num === item.hangGroupID)
          ) {
            return item.order < min.order ? item : min;
          }
          return undefined; // 如果没有找到，则返回undefined
        });

        if (!Tsrv.noValue(minOrderItem)) {
          this.reserveHangGroupInfo = minOrderItem;
        }
      }

      filterVal.forEach(el => {
        if (
          el.f_status > 1 &&
          el.f_status < 5 &&
          el.physical_num !== this.reserveHangGroupInfo.hangGroupID
        ) {
          scheData.push(el);
        }
      });
      // 单挂排程没有意义
      if (scheData.length >= 2) {
        // 重置缓存位顺序
        this.resetCache(scheData);
      }
    } else {
      // 没有加工中的挂组，则不需要预留挂组
      filterVal.forEach(el => {
        if (el.f_status > 1 && el.f_status < 5) {
          scheData.push(el);
        }
      });
      if (scheData.length >= 3) {
        const hangGroups = [];
        scheData.forEach(el => {
          hangGroups.push(el.physical_num);
        });
        this.self.sendLogOut(`挂组${hangGroups}开始排程`);
        this.getRegisterJson(scheData);
      }
    }
  }

  // 重置缓存位
  private resetCache(data: Array<any>) {
    // 现场行车调用逻辑：每次选取顺序最小的缓存位
    // 将重新排程的缓存位挂组id清空，写0处理，将预留位的顺序设为1，预留位变成最小缓存位，无论排程结果是否出来，优先调用预留位
    const writeData = [];
    const hangGroups = [];
    this.currentCacheStatus.forEach(el => {
      if (el.hangGroupID === this.reserveHangGroupInfo.hangGroupID) {
        writeData.push({
          ecDetCode: el.cacheOrderp,
          value: '1'
        });
      } else {
        writeData.push({
          ecDetCode: el.cacheOrderp,
          value: '0'
        });
        hangGroups.push(el.hangGroupID);
      }
    });

    this.self.sendLogOut(
      `挂组${hangGroups}开始排程,此时预留位为${this.reserveHangGroupInfo.hangGroupID}`
    );
    this.writePlcData(writeData).then(success => {
      if (success) {
        // 调用排程
        this.getRegisterJson(data);
      }
    });
  }

  // 组装排程注册json
  public getRegisterJson(datas: Array<any>) {
    // 根据挂组信息组装event参数
    const hangGroups = [];
    datas.forEach(el => {
      const obj = {
        hang_groups_num: el['physical_num'],
        process_flow_num: el['process_flow_num']
      };
      hangGroups.push(obj);
    });
    const gridFunInfo = Tsrv.getFunInfo(this.tableName.pLDetails);
    const params = () => {
      return {
        funName: 'cPLDetails',
        title: 'customFun',
        from: 'cPLDetails',
        data: {
          hangGroups
        }
      };
    };
    Tsrv.doEvent('my_make_schedule_json', gridFunInfo, params).then(res => {
      if (res.isErr()) {
        this.self.$msg(res.errmsg);
      } else {
        // 根据event返回内容组装排程注册json
        const returnData = res.getReturnData('conf');
        const orginData: N_cPLDetails.I_schedulRegis = returnData.res.data.data;
        const cranes = orginData.cranes.map(el => {
          Object.keys(el).forEach(key => {
            if (key !== 'code') {
              el[key] = Number(el[key]);
            }
          });
          return el;
        });
        const registerInfo = {
          taskConfig: {
            groupSize: 20,
            maxOnlineCountToReloadRate: 1
          },
          cranes,
          places: [
            {
              code: '上下料工位',
              x: 0,
              y: 0,
              operationName: '上下料工位',
              type: '上下料工位'
            },
            {
              code: '加工缓存工位1',
              x: 5019,
              y: 0,
              operationName: '加工缓存工位',
              type: '加工缓存工位'
            },
            {
              code: '加工缓存工位2',
              x: 4048,
              y: 0,
              operationName: '加工缓存工位',
              type: '加工缓存工位'
            },
            {
              code: '加工缓存工位3',
              x: 3019,
              y: 0,
              operationName: '加工缓存工位',
              type: '加工缓存工位'
            },
            {
              code: '加工缓存工位4',
              x: 2019,
              y: 0,
              operationName: '加工缓存工位',
              type: '加工缓存工位'
            }
          ],
          hangGroups: []
        };
        this.defaulTimes = [];
        orginData.hangGroups.forEach(el => {
          const hangGroupInfo = {
            code: el.hangGroupNum,
            operationList: []
          };
          // 每一挂加工默认时间
          const defaultTime = {
            code: el.hangGroupNum,
            machTime: 60 // 每一挂从上料位到缓存位，再到交换位，再到化学除油位默认时间为60秒
          };
          el.processInfo.forEach(el2 => {
            const workTime = el2?.processParams?.workTime;
            const temp =
              el2?.processParams?.tempRange && el2?.processParams?.tempFluc;

            const processInfo = {
              id: Tsrv.getSnowIDFmtStr(),
              maxTime: workTime ? el2.processParams.workTime : 1, // 默认本道工序加工时间1秒
              minTime: workTime ? el2.processParams.workTime - 1 : 0,
              name: el2.processID
            };
            if (workTime) {
              // 行车升降默认时间为31秒
              defaultTime.machTime += workTime + 31;
            } else {
              // 默认本道工序加工时间1秒
              defaultTime.machTime += 32;
            }
            if (temp) {
              processInfo['tempRange'] = {
                from: el2.processParams.tempRange - el2.processParams.tempFluc,
                to: el2.processParams.tempRange + el2.processParams.tempFluc
              };
            }
            const arr = registerInfo.places.find(
              el3 => el3.code === el2.pslotInfo.slotID
            );
            if (Tsrv.noValue(arr)) {
              const placeInfo = {
                code: el2.pslotInfo.slotID,
                x: el2.pslotInfo.x,
                y: Number(el2.pslotInfo.y),
                operationName: el2.processID,
                type: '工艺槽'
              };
              if (temp) {
                placeInfo['tempRange'] = {
                  from:
                    el2.processParams.tempRange - el2.processParams.tempFluc,
                  to: el2.processParams.tempRange + el2.processParams.tempFluc
                };
              }
              registerInfo.places.push(placeInfo);
            }
            hangGroupInfo.operationList.push(processInfo);
          });
          this.defaulTimes.push(defaultTime);
          registerInfo.hangGroups.push(hangGroupInfo);
        });
        this.schedulingJson = registerInfo;

        // 组装完毕开始排程
        this.openScheduling(this.schedulingJson);
      }
    });
  }

  // 开启排程
  private openScheduling(registerInfo: any) {
    const params = JSON.stringify(registerInfo);
    Tsrv.standardPostReq<N_cPLDetails.I_schedulingResp, any>(
      params,
      'http://192.168.31.50:21030/matrix/register',
      {
        headers: {
          'Content-Type': 'application/json'
        },
        isExternalReq: true
      }
    ).then(([res, e]) => {
      if (res.code !== 200) {
        this.self.$msg(res.message);
        this.schedulingFailHandle(); // 排程失败，提示报错信息然后移除所有任务并退回等待状态
      } else {
        // 当前排程任务id
        this.taskID = res.data;
        // 当前排程任务状态
        this.schedulingStatus = N_cPLDetails.V_reqStatus.RUNNING;
        const data = [];
        const logData = [];
        this.schedulingItems = [];
        registerInfo.hangGroups.forEach(el => {
          this.schedulingItems.push(el.code);
          const updateData = [
            {
              field: this.filterName.physicalNum,
              value: el.code
            } as ifs.I_fv,
            {
              field: 'f_status',
              value: 3
            } as ifs.I_fv
          ];
          const logDataItems = [
            {
              field: 'id',
              value: Tsrv.getSnowIDFmtStr()
            } as ifs.I_fv,
            {
              field: 'master_bill_id',
              value: this.topBaseGrid.cloudData.find(
                el1 => el1.physical_num === Number(el.code)
              ).id
            } as ifs.I_fv,
            {
              field: 'title',
              value: `挂组排程中，排程id为${this.taskID}`
            } as ifs.I_fv
          ];
          data.push(updateData);
          logData.push(logDataItems);
        });
        this.modifyData(
          this.tableName.pLDetails,
          this.filterName.physicalNum,
          data
        ).then(success => {
          if (success) {
            this.addTableData(this.tableName.hGSupplementInfo, logData);
          }
        });
        // 开启排程
        Tsrv.standardGetReq<N_cPLDetails.I_schedulingResp, any>(
          { taskId: res.data },
          'http://192.168.31.50:21030/matrix/process'
        ).then(([res2, e2]) => {
          if (res2.code !== 200) {
            this.self.$msg(res2.message);
            this.schedulingFailHandle(); // 排程失败，提示报错信息然后移除所有任务并退回等待状态
          } else {
            // 开启轮询，循环读取排程结果
            this.scheduleTask.addTask(this.getTaskStatus);
            this.scheduleTask.startTask(); // 开始轮询
          }
        });
      }
    });
  }

  // 排程失败处理
  private schedulingFailHandle() {
    // 将排程中的挂组退回到等待状态，并提示算法服务异常，请联系管理员
    this.self.$msg(Tsrv.getI18nByValue('算法服务异常，请联系管理员'));
    this.self.sendLogOut({
      content: `挂组${this.schedulingItems}排程失败,将退回到等待状态`,
      isErr: true
    });
    this.removeAllTask().then(_ => {
      if (!Tsrv.noValue(this.schedulingItems)) {
        const data = [];
        this.schedulingItems.forEach(el => {
          const updateData = [
            {
              field: this.filterName.physicalNum,
              value: el
            } as ifs.I_fv,
            {
              field: 'f_status',
              value: 0
            } as ifs.I_fv
          ];
          data.push(updateData);
        });
        this.modifyData(
          this.tableName.pLDetails,
          this.filterName.physicalNum,
          data
        );
      }
    });
  }

  // 获取任务状态
  public getTaskStatus = () => {
    Tsrv.standardGetReq<N_cPLDetails.I_schedulingResp, any>(
      { taskId: this.taskID },
      'http://192.168.31.50:21030/matrix/getStatus'
    ).then(([res, e]) => {
      if (res.code !== 200) {
        this.self.$msg(res.message);
        // this.task.delTask(this.getTaskStatus); // 清除该轮询任务
        this.scheduleTask.delTask(this.getTaskStatus);
        this.scheduleTask.stopTask();
        if (!Tsrv.noValue(this.taskID)) {
          this.schedulingFailHandle(); // 排程失败，提示报错信息然后移除所有任务并退回等待状态
        }
      } else {
        if (res.data['status'] === 'COMPLETE') {
          // 清除该轮询任务
          // this.task.delTask(this.getTaskStatus);
          this.scheduleTask.delTask(this.getTaskStatus);
          this.scheduleTask.stopTask();
          // 排程完毕，可以查看结果（基于挂组）
          Tsrv.standardGetReq<N_cPLDetails.I_schedulingResp, any>(
            { taskId: this.taskID },
            'http://192.168.31.50:21030/matrix/getResultGroupByHangGroup'
          ).then(([res1, e1]) => {
            if (res1.code !== 200) {
              this.self.$msg(res1.message);
              this.schedulingFailHandle(); // 排程失败，提示报错信息然后移除所有任务并退回等待状态
            } else {
              // 1.更新排程状态为FINISHED
              // 2.排程正常更改挂组状态为已排程
              // 3.将排程后的挂组顺序写入缓存位
              // 4.组装json调用仿真api
              // 5.移除所有排程任务
              // 处理1
              this.schedulingStatus = N_cPLDetails.V_reqStatus.FINISHED;

              const times = [];
              const data = [];
              // 获取挂组id与对应顺序,挂组id为code字段，顺序为index下标；
              const orders = {};
              res1.data.hangGroupVos.forEach((el, index) => {
                times.push({
                  code: el.code,
                  startTime: el.startTime,
                  endTime: el.endTime
                });
                data.push([
                  {
                    field: this.filterName.physicalNum,
                    value: el.code
                  } as ifs.I_fv,
                  {
                    field: 'f_status',
                    value: 4
                  } as ifs.I_fv,
                  {
                    field: 'expect_start_time',
                    value: el.startTime
                  } as ifs.I_fv,
                  {
                    field: 'expect_end_time',
                    value: el.endTime
                  } as ifs.I_fv
                ]);
                // 判断是否存在预留位，如果存在，预留位永远为最小值1，其他排程挂组从2开始
                if (Tsrv.noValue(this.reserveHangGroupInfo.hangGroupID)) {
                  orders[el.code] = index + 1;
                } else {
                  orders[el.code] = index + 2;
                }
              });
              // 处理2
              this.updateHangGroupStatus(data);
              // 处理3
              this.writeCacheOrder(orders);
              // 处理4
              this.getProcessTime(times);
              // 处理5
              this.removeAllTask();
            }
          });
        }
      }
    });
  };

  // 排程正常更新挂组状态为已排程
  private updateHangGroupStatus(data: Array<Array<ifs.I_fv>>) {
    // 智能排产明细与产线明细管理合并成一张表在首页显示，因此只需要修改该挂组的越级开始，结束时间即可
    this.modifyData(
      this.tableName.pLDetails,
      this.filterName.physicalNum,
      data
    ).then(success => {
      if (success) {
        const rows = data.map(el => {
          const row = [
            {
              field: 'id',
              value: Tsrv.getSnowIDFmtStr()
            } as ifs.I_fv,
            {
              field: 'title',
              value: `该挂组已排程，排程id为${this.taskID}`
            } as ifs.I_fv
          ];
          el.forEach(el1 => {
            if (el1.field === this.filterName.physicalNum) {
              const id = this.topBaseGrid.cloudData.find(
                el2 => el2.physical_num === Number(el1.value)
              ).id;
              row.push({
                field: 'master_bill_id',
                value: id
              } as ifs.I_fv);
            }
          });
          return row;
        });
        this.taskID = undefined;
        this.addTableData(this.tableName.hGSupplementInfo, rows);
        this.self.sendLogOut(`挂组${this.schedulingItems}已排程`);
      }
    });
  }

  // 将排程后的挂组顺序写入缓存位
  private writeCacheOrder(orders: any) {
    const readDatas = [];
    this.cacheInfo.forEach((value, key) => {
      readDatas.push(value.hangGroupIdp);
    });
    // 读取当前缓存位的挂组id，如果读取值为0则该缓存位为空，根据挂组id与当前排程的挂组id对比，写入缓存位顺序
    this.readPlcData(readDatas).then(res2 => {
      if (typeof res2 === 'boolean') return;

      const writeDatas = [];
      this.currentCacheStatus = [];

      // 如果存在预留位，当前缓存位状态也包括预留位
      if (!Tsrv.noValue(this.reserveHangGroupInfo.hangGroupID)) {
        this.currentCacheStatus.push(this.reserveHangGroupInfo);
      }

      this.cacheInfo.forEach((value, _) => {
        if (orders[res2[value.hangGroupIdp].v] !== undefined) {
          this.currentCacheStatus.push({
            hangGroupID: res2[value.hangGroupIdp].v,
            cacheStatusp: value.hangGroupStatusp,
            order: orders[res2[value.hangGroupIdp].v],
            cacheOrderp: value.cacheOrderp
          });

          writeDatas.push({
            ecDetCode: value.cacheOrderp,
            value: orders[res2[value.hangGroupIdp].v]
          });
        }
      });
      if (!Tsrv.noValue(writeDatas)) {
        this.writePlcData(writeDatas, true).then(success => {
          if (success) {
            // 写入缓存位成功，轮询问该挂组是否开始加工，开始加工则更新挂组状态
            // 读取hangGroupStatus中的点，具体读哪个点根据写的缓存位而定
            // 加工顺序
            const processSeq = [];
            const readCodes = this.currentCacheStatus.map(el => {
              processSeq.push(`${el.order}-${el.hangGroupID}`);
              return el.cacheStatusp;
            });
            readCodes.forEach(code => {
              if (this.ecDetCodeList.indexOf(code) === -1) {
                this.ecDetCodeList.push(code);
                // Tsrv.myECR.addEcCodeList([code]);
              }
            });
            this.self.sendLogOut(`写入缓存位成功,此时加工顺序为${processSeq}`);
          }
        });
      }
    });
  }

  private writeCacheOrder1(orders: any) {
    const writeDatas = this.currentCacheStatus.map(item => {
      return {
        ecDetCode: item.cacheOrderp,
        value: orders[item.hangGroupID]
      };
    });

    // 如果存在预留位，当前缓存位状态也包括预留位
    if (!Tsrv.noValue(this.reserveHangGroupInfo.hangGroupID)) {
      this.currentCacheStatus.push(this.reserveHangGroupInfo);
    }

    this.writePlcData(writeDatas, true).then(success => {
      if (success) {
        // 读取该挂组是否开始加工
        const processSeq = [];
        this.currentCacheStatus.forEach(item => {
          processSeq.push(`${item.order}-${item.hangGroupID}`);
          if (this.ecDetCodeList.indexOf(item.cacheStatusp) === -1) {
            this.ecDetCodeList.push(item.cacheStatusp);
            // Tsrv.myECR.addEcCodeList([item.cacheStatusp]);
          }
        });
        this.self.sendLogOut(`写入缓存位成功,此时加工顺序为${processSeq}`);
      }
    });
  }

  // 根据排程后的挂组结果组装仿真json参数
  private assembleSimulateJson(
    startTimes: any[],
    timeType: string
  ): Promise<number | boolean> {
    // 仿真的行车参数还存在问题
    const cranes = [
      {
        code: '1号',
        minX: 0,
        maxX: 33012,
        startX: 0,
        xAccStart: 145,
        xSpeedMax: 578,
        xAccEnd: -145,
        upAcc: 145,
        upSpeedMax: 578,
        downAcc: 145,
        downSpeedMax: 578,
        height: 5780
      },
      {
        code: '2号',
        minX: 31672,
        maxX: 43772,
        startX: 32000,
        xAccStart: 145,
        xSpeedMax: 578,
        xAccEnd: -145,
        upAcc: 145,
        upSpeedMax: 578,
        downAcc: 145,
        downSpeedMax: 145,
        height: 5780
      }
    ];
    const places = [];
    // 上下料工位
    const upDownPlace = [
      {
        code: '上料工位',
        x: 0,
        y: 0,
        operationName: null,
        type: '上料工位',
        active: true,
        highestPriority: false,
        switch2to1: false,
        switch1to2: false,
        priority: 0
      },
      {
        code: '下料工位',
        x: 0,
        y: 0,
        operationName: null,
        type: '下料工位',
        active: true,
        highestPriority: false,
        switch2to1: false,
        switch1to2: false,
        priority: 0
      }
    ];
    places.push(...upDownPlace);
    // 工艺槽
    this.schedulingJson.places.forEach(item => {
      if (item.type === '工艺槽') {
        const place = {
          code: item.code,
          type: item.type,
          operationName: item.operationName,
          x: item.x,
          active: true,
          highestPriority: false,
          priority: 1,
          switch2to1: false,
          switch1to2: false
        };
        places.push(place);
      } else if (item.type === '加工缓存工位') {
        const place = {
          code: item.code,
          type: item.type,
          operationName: null,
          x: item.x,
          active: true,
          highestPriority: false,
          priority: 0,
          switch2to1: false,
          switch1to2: false
        };
        places.push(place);
      }
    });
    // 交换位
    const exChangePlace = [
      {
        code: '10号',
        type: '交换槽',
        operationName: null,
        x: 31672,
        active: true,
        highestPriority: false,
        priority: 1,
        switch2to1: false,
        switch1to2: true
      },
      {
        code: '9号',
        type: '交换槽',
        operationName: '冷水洗',
        x: 33012,
        active: true,
        highestPriority: false,
        priority: 1,
        switch2to1: true,
        switch1to2: false
      }
    ];
    places.push(...exChangePlace);
    const reqJson = {
      craneSafeDistance: 2824,
      craneSafePlaceDistance: 2,
      placeSpace: 2824,
      places,
      cranes,
      hangGroups: this.schedulingJson.hangGroups
    };
    reqJson.hangGroups.forEach(el => {
      startTimes.forEach(el1 => {
        if (el.code === el1.code) {
          el.planStartTime = el1.startTime;
        }
      });
    });
    return new Promise((resolve, reject) => {
      Tsrv.standardPostReq<N_cPLDetails.I_schedulingResp, any>(
        reqJson,
        'http://192.168.31.50:21030/matrix/getMySimulationResultGroupByHangGroup',
        {
          headers: {
            'Content-Type': 'application/json'
          },
          isExternalReq: true
        }
      ).then(([res, e]) => {
        if (res.code !== 200) {
          this.self.$msg(res.message);
          this.self.sendLogOut({
            content: '仿真调用失败，请联系管理员查看',
            isErr: true
          });
          reject(false);
        } else {
          // 仿真调用成功
          // 调用两次仿真计算，一次未排程的，一次为排程的，计算时间差
          res.data.hangGroupVos.forEach(el => {
            const startTime: any = new Date(el.startTime);
            const endTime: any = new Date(el.endTime);
            const timeDifference = endTime - startTime;
            this.schedulingTime[timeType] += timeDifference;
          });
          resolve(true);
        }
      });
    });
  }

  // 移除所有任务
  public removeAllTask(): Promise<boolean> {
    return new Promise((resolve, reject) => {
      axios
        .delete('http://192.168.31.50:21030/matrix/removeAll', {
          headers: {
            'Accept-Language': 'zh'
          }
        })
        .then(res => {
          if (res.data.code !== 200) {
            this.self.$msg(res.data.msg);
            reject(false);
          } else {
            resolve(true);
          }
        });
    });
  }

  // 计算加工时长
  public getProcessTime(times: any[]) {
    this.schedulingTime.default = 0;
    this.schedulingTime.intelligent = 0;
    this.self.sendLogOut('开启仿真运算');
    this.assembleSimulateJson(times, 'intelligent').then(success => {
      if (success) {
        this.defaulTimes[0].startTime = times[0].startTime;
        for (let index = 0; index < this.defaulTimes.length - 1; index++) {
          const endTime = this.addSecondsToTime(
            times[0].startTime,
            this.defaulTimes[index].machTime
          );
          this.defaulTimes[index + 1].startTime = endTime;
        }
        this.assembleSimulateJson(this.defaulTimes, 'default').then(
          success1 => {
            if (success1) {
              this.addSimulateTime();
            }
          }
        );
      }
    });
  }

  // 新增仿真排程时间
  private addSimulateTime() {
    let groupHangs = '';
    for (let index = 0; index < this.defaulTimes.length; index++) {
      if (index === this.defaulTimes.length - 1) {
        groupHangs += this.defaulTimes[index].code;
      } else {
        groupHangs += `${this.defaulTimes[index].code},`;
      }
    }
    const data = [
      [
        {
          field: 'id',
          value: Tsrv.getSnowIDFmtStr()
        } as ifs.I_fv,
        {
          field: 'title',
          value: groupHangs
        } as ifs.I_fv,
        {
          field: 'default_sche_time',
          value: this.schedulingTime.default
        } as ifs.I_fv,
        {
          field: 'Intel_sche_time',
          value: this.schedulingTime.intelligent
        } as ifs.I_fv,
        {
          field: 'production_line',
          value: this.self.formData.id
        } as ifs.I_fv
      ]
    ];
    this.addTableData(this.tableName.sSTime, data).then(success => {
      if (success) {
        this.sendBusEvent(this.commonEvent.scheTime, [this.self.formData.id]);
      }
    });
    const defaultTime = this.changeTimeFormat(this.schedulingTime.default);
    const intelligentTime = this.changeTimeFormat(
      this.schedulingTime.intelligent
    );
    const saveTime = this.changeTimeFormat(
      this.schedulingTime.default - this.schedulingTime.intelligent
    );
    this.self.sendLogOut(
      `仿真完成，本次仿真默认排程时间${defaultTime}，智能排程时间${intelligentTime}，节省时间${saveTime}`
    );
  }
}
interface I_scheduleHandle extends T_shceduleHandle {}
export { I_scheduleHandle, T_shceduleHandle };
